Apache

您所在的位置:网站首页 temporal temporary 区别 Apache

Apache

2024-01-07 02:40| 来源: 网络整理| 查看: 265

5万人关注的大数据成神之路,不来了解一下吗?

5万人关注的大数据成神之路,真的不来了解一下吗?

5万人关注的大数据成神之路,确定真的不来了解一下吗?

欢迎您关注《大数据成神之路》

在《JOIN LATERAL》中提到了Temporal Table JOIN,本篇就向大家详细介绍什么是Temporal Table JOIN。 在ANSI-SQL 2011 中提出了Temporal 的概念,Oracle,SQLServer,DB2等大的数据库厂商也先后实现了这个标准。Temporal Table记录了历史上任何时间点所有的数据改动,Temporal Table的工作流程如下:

上图示意Temporal Table具有普通table的特性,有具体独特的DDL/DML/QUERY语法,时间是其核心属性。历史意味着时间,意味着快照Snapshot。

我们以一个DDL和一套DML示例说明Temporal Table的原理,DDL定义PK是可选的,下面的示例我们以不定义PK的为例进行说明:

DDL 示例CREATE TABLE Emp ENo INTEGER, Sys_Start TIMESTAMP(12) GENERATED ALWAYS AS ROW Start, Sys_end TIMESTAMP(12) GENERATED ALWAYS AS ROW END, EName VARCHAR(30), PERIOD FOR SYSTEM_TIME (Sys_Start,Sys_end) ) WITH SYSTEM VERSIONINGDML 示例INSERTINSERT INTO Emp (ENo, EName) VALUES (22217, 'Joe')

说明: 其中Sys_Start和Sys_End是数据库系统默认填充的。

UPDATEUPDATE Emp SET EName = 'Tom' WHERE ENo = 22217

说明: 假设是在 2012-02-03 10:00:00 执行的UPDATE,执行之后上一个值"Joe"的Sys_End值由9999-12-31 23:59:59 变成了 2012-02-03 10:00:00, 也就是下一个值"Tom"生效的开始时间。可见我们执行的是UPDATE但是数据库里面会存在两条数据,数据值和有效期不同,也就是版本不同。

DELETE (假设执行DELETE之前的表内容如下) DELETE FROM Emp WHERE ENo = 22217

说明: 假设我们是在2012-06-01 00:00:00执行的DELETE,则Sys_End值由9999-12-31 23:59:59 变成了 2012-06-01 00:00:00, 也就是在执行DELETE时候没有真正的删除符合条件的行,而是系统将符合条件的行的Sys_end修改为执行DELETE的操作时间。标识数据的有效期到DELETE执行那一刻为止。

SELECTSELECT ENo,EName,Sys_Start,Sys_End FROM Emp FOR SYSTEM_TIME AS OF TIMESTAMP '2011-01-02 00:00:00'

说明: 这个查询会返回所有Sys_Start 2011-01-02 00:00:00 的记录。

SQLServer Temporal Table 示例DDLCREATE TABLE Department ( DeptID int NOT NULL PRIMARY KEY CLUSTERED , DeptName varchar(50) NOT NULL , ManagerID INT NULL , ParentDeptID int NULL , SysStartTime datetime2 GENERATED ALWAYS AS ROW Start NOT NULL , SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL , PERIOD FOR SYSTEM_TIME (SysStartTime,SysEndTime) ) WITH (SYSTEM_VERSIONING = ON);

执行上面的语句,在数据库会创建当前表和历史表,如下图:

Department 显示是有版本控制的,历史表是默认的名字,我也可以指定名字如:SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.DepartmentHistory)。

DMLINSERT - 插入列不包含SysStartTime和SysEndTime列INSERT INTO [dbo].[Department]([DeptID] ,[DeptName] ,[ManagerID] ,[ParentDeptID]) VALUES(10, 'Marketing', 101, 1);

执行之后我们分别查询当前表和历史表,如下图:

我们第一条INSERT语句数据值的有效时间是操作那一刻2018-06-06 05:50:20.7913985 到永远 9999-12-31 23:59:59.9999999,但这时刻历史表还没有任何信息。我们接下来进行更新操作。

UPDATEUPDATE [dbo].[Department] SET [ManagerID] = 501 WHERE [DeptID] = 10执行之后当前表信息会更新并在历史表里面产生一条历史信息,如下:

注意当前表的SysStartTime意见发生了变化,历史表产生了一条记录,SyStartTIme是原当前表记录的SysStartTime,SysEndTime是当前表记录的SystemStartTime。我们再更新一次:

UPDATE [dbo].[Department] SET [ManagerID] = 201 WHERE [DeptID] = 10

到这里我们了解到SQLServer里面关于Temporal Table的逻辑是有当前表和历史表来存储数据,并且数据库内部以StartTime和EndTime的方式管理数据的版本。

SELECT SELECT [DeptID], [DeptName], [SysStartTime],[SysEndTime] FROM [dbo].[Department] FOR SYSTEM_TIME AS OF '2018-06-06 05:50:21.0000000' ;

SELECT语句查询的是Department的表,实际返回的数据是从历史表里面查询出来的,查询的底层逻辑就是 SysStartTime '2018-06-06 05:50:21.0000000' 。

Apache Flink Temporal Table

我们不止一次的提到Apache Flink遵循ANSI-SQL标准,Apache Flink中Temporal Table的概念也源于ANSI-2011的标准语义,但目前的实现在语法层面和ANSI-SQL略有差别,上面看到ANSI-2011中使用FOR SYSTEM_TIME AS OF的语法,目前Apache Flink中使用 LATERAL TABLE(TemporalTableFunction)的语法。这一点后续需要推动社区进行改进。

为啥需要 Temporal Table我们以具体的查询示例来说明为啥需要Temporal Table,假设我们有一张实时变化的汇率表(RatesHistory),如下:

rowtime(ts)

currency(pk)

rate

09:00:00

US Dollar

102

09:00:00

Euro

114

09:00:00

Yen

1

10:45:00

Euro

116

11:15:00

Euro

119

11:49:00

Pounds

108

RatesHistory代表了Yen汇率(Yen汇率为1),是不断变化的Append only的汇率表。例如,Euro兑Yen汇率从09:00至10:45的汇率为114。从10点45分到11点15分是116。

假设我们想在10:58输出所有当前汇率,我们需要以下SQL查询来计算结果表:

SELECT * FROM RatesHistory AS r WHERE r.rowtime = ( SELECT MAX(rowtime) FROM RatesHistory AS r2 WHERE r2.currency = r.currency AND r2.rowtime


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3